文件型外置记忆
为何选文件系统而非向量库、CLAUDE.md 四级分层加载的设计取向与工程实践
核心要点:
- 记忆放文件系统,可检视可版本控制
- "98.4% 确定性基础设施"取向决定文件优于向量库
- CLAUDE.md 四级分层加载
- MEMORY.md 做索引,详情按需读取
- 文件 compaction 后可从磁盘重注入
文件型记忆与 05-向量检索记忆 是两条并行路径:前者人可读、可 git,后者高密度、语义检索。本文讲文件路径的设计取向与分层结构。
为什么用文件系统而不是向量数据库存记忆?
核心问题:既然有现成的向量数据库,coding agent 为什么把记忆放进 Markdown 文件?
因为可检视性比检索密度更符合"确定性基础设施"的工程取向[1]。对 Claude Code 的源码分析发现,它只有 1.6% 是 AI 决策逻辑,其余 98.4% 是权限门、上下文管理、工具路由这类确定性基础设施——这一取向直接决定记忆用文件而非黑箱向量库。
文件型记忆的四个具体优势:
- 可检视:人能直接
cat/git diff看记忆内容,不需要查向量库。 - 可编辑:用户能精确修改或删除任意条目。
- 可版本控制:项目 CLAUDE.md 随代码进入 git,记忆与代码同源演进。
- 无黑箱:检索是 LLM 扫描文件头(每次最多选 5 个相关文件),而非不透明的相似度匹配。
可借鉴的判断:当记忆条目需要人审、需要随项目演进时,文件优于向量库;当记忆是海量、非结构化、只靠语义召回时,才轮到向量检索。
分层记忆怎么组织?
核心问题:个人偏好、团队规范、合规策略——这些不同来源的记忆怎么不打架?
CLAUDE.md 按作用域分四级,从宽到窄优先级递增[2]。分层让不同来源的记忆各归其位。
| 层级 | 路径 | 写入者 | 共享范围 |
|---|---|---|---|
| Managed Policy | 系统级路径 | IT / DevOps | 机器所有用户 |
| User | ~/.claude/CLAUDE.md | 用户 | 本人所有项目 |
| Project | ./CLAUDE.md 或 ./.claude/CLAUDE.md | 团队 | 团队(经 git) |
| Local | ./CLAUDE.local.md(gitignore) | 用户 | 本人当前项目 |
@tbl-agent-memory-claude-md-layers CLAUDE.md 四级分层加载:Managed Policy、User、Project、Local 的路径、写入者与共享范围
更细粒度的规则放 .claude/rules/ 目录,支持 paths frontmatter 按文件类型条件加载——只在 agent 操作匹配文件时触发,避免无关规则占 token。
自动记忆走另一套 MEMORY.md 系统:MEMORY.md 是索引文件,每次会话加载前 200 行或 25KB;详细内容分入 topic 文件(如 debugging.md),按需读取而非全量加载。这是"索引 + 惰性加载"模式,把记忆总量与每次加载量解耦。
例子:一个项目的记忆目录可能长这样——
~/.claude/projects/<proj>/memory/
├── MEMORY.md # 索引,每次加载前 200 行/25KB
├── debugging.md # 调试笔记,按需读
└── api-conventions.md # API 决策,按需读
./CLAUDE.md # 项目级,随 git 共享
./.claude/rules/*.md # 条件加载规则(paths 触发)检索不靠向量相似度,而是 LLM 扫描各文件头部的描述、每次最多选 5 个相关文件加载——这让"召回哪段记忆"这件事本身也是可检视、可调试的。
跨会话怎么交接?
核心问题:会话结束上下文清空,下一个 agent 怎么知道之前做到哪?
用结构化 handoff 文档桥接:一个 agent 写文件,另一个 agent 读文件续跑[3]。这是 context-reset 策略可行的前提(与 compaction 的对比详见 03-compaction)。
handoff 文档携带三类信息:上一个 agent 的状态(做完什么、决策了什么)、下一步任务列表、关键依赖与上下文片段。它把"跨会话"从信息丢失变成可控交接——新 agent 通过文件获得足够的接续信息,而不是继承一段被 context anxiety 污染的长历史。
底层会话存储也为此设计:append-only JSONL transcript 增量写入不破坏旧数据,compact 边界用 headUuid/tailUuid 在读取时 patch 消息链,磁盘上不做破坏性修改。
compaction 会丢掉文件记忆吗?
核心问题:上下文被压缩后,CLAUDE.md 里的规范还在吗?
不会丢——compaction 后 Claude 从磁盘重新读取 CLAUDE.md 并重新注入会话[2]。这是文件型记忆相对纯对话历史的关键优势。
纯对话历史里的信息随压缩消失;文件是外部锚点,压缩之后可以重新加载。换句话说,文件型记忆把"必须记住的"从易失的对话上下文里搬到了持久的磁盘上,让它免疫于压缩损失。这条设计原则可推广:任何不能丢的状态,都应落到压缩边界之外的外部存储,而非寄望于上下文窗口保留。
Takeaway
| 知识点 | 核心结论 |
|---|---|
| 文件 vs 向量库 | 可检视/可 git 胜过检索密度,契合"确定性基础设施"取向 |
| CLAUDE.md 四级 | Managed / User / Project / Local,作用域从宽到窄 |
| 条件加载 | .claude/rules/ 按文件类型 paths 触发,省 token |
| MEMORY.md | 索引 + topic 文件按需加载,总量与加载量解耦 |
| handoff | 写文件—读文件桥接,使 context-reset 不丢信息 |
| 免疫压缩 | 文件 compaction 后从磁盘重注入,不随摘要消失 |
参考资料
- Liu et al. Dive into Claude Code: The Design Space of Today's and Future AI Agent Systems. arXiv:2604.14228, 2026. https://arxiv.org/abs/2604.14228
- Claude Code Docs. How Claude remembers your project. 2026. https://code.claude.com/docs/en/memory
- Anthropic. Harness design for long-running application development. 2025. https://www.anthropic.com/engineering/harness-design-long-running-apps